package com.peaksport.pkms.learntest.controller;

import java.util.HashMap;
import java.util.Map;

import javax.ws.rs.core.MediaType;

import org.apache.servicecomb.pack.omega.context.annotations.TccStart;
import org.apache.servicecomb.provider.rest.common.RestSchema;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import com.peaksport.framework.base.controller.BaseController;
import com.peaksport.pkms.learntest.service.TestPackTccService;

/**
 * 测试分布式事务框架Pack tcc模式
 * 测试结论:
 *  1. sagaUI需改进
 *    a. tcc模式下 sagaUI全没有体现
 *  2. confirm事务实际是没有参与单微服务的事务的，而是在全局事务通过过，再异步启动的，所以也就导致了即时异常对返回结果也未知
 *  
 *
 * 
 *
 * @author jinbin_guo 2019年5月12日
 *
 */

@RestSchema(schemaId="pkms-test-pack-tcc")
@RequestMapping(value="test/pack/tcc",produces=MediaType.APPLICATION_JSON)
public class TestPackTccController extends BaseController {
	
	@Autowired
	private TestPackTccService servcie;

	private String cseService2 = "cse://pkms-test1/test1/pack/tcc/tesAuditBillEtryForTcc?billId={billId}&isException={isException}&isExceptionInConfirm={isExceptionInConfirm}&isExceptionInCancel={isExceptionInCancel}";

	/**
	 * 测试案例: 
	 *  1. 业务场景:
	 *    a. 共有2个 微服务,暂命名micservcie1&micservcie2
	 *    b. 在micservcie1里的controller里调用micservcie2
	 *    c. 服务调用采用同步调用的方式，非异步
	 *  2. 名称约定:
	 *    a. try表示在@Serivce中@Participate的try方法 
	 *    a. confirm表示在@Serivce中@Participate的提交方法
	 *    b. cancel表示再@service中@Participate的补偿方法
	 *    c. controller_invoke_service_after表示controller调用@service之后
	 *    d. controller_invoek_service_before表示controller调用@service之前
	 *    
	 * 
	 *  在Controller中调用第2个微服务事务
	 * http://127.0.0.1:9000/pkms/test/test/pack/tcc/testInvokeInController?billId=TLM%2FQ%2Bh%2FRr%2BqihLqUe6Tily2lGM%3D&isException=false&isExceptionInConfirm=true&isExceptionInCancel=false&isException_service2=false&isExceptionInConfirm_service2=false&isExceptionInCancel_service2=false
	 *   
	 *  
	 * 结果: 
	 * 	a. 当micservice1.confirm发生异常, micservice2正常被调用了,micservice1.cancel也未执行，结果不会返回异常信息，这里可能需要人为的补偿,但没配套的UI,现在很不方便
	 *  b. 当micservice1.try发生异常,  micservice2未被调用，micservice1.try事务未提交
	 *  c. 当micservice2.confirm发生异常,  micservice1正常被调用了,micservice2.cancel也未执行，，结果不会返回异常信息，这里可能需要人为的补偿,但没配套的UI,现在很不方便
	 *  d. 当micservice2.try发生异常，micservice2.try事务未提交，micservice1.cancel被执行，micservice1.confirm未执行
	 *  e. 当micservice2.try发生异常,micservice1.cancle发生异常,micservice2.try事务未提交，micservice1的补偿事务如何体现
	 *  f. 当micservice1.controller_invoke_service_after发生异常,micservcie1.cancel&micservcie2.cancle都被执行，confirm不会执行
	 *  g. 当micservice2.controller_invoke_service_after发生异常,micservcie1.cancel&micservcie2.cancle都被执行，confirm不会执行
	 *  
	 * @return
	 */
	@TccStart	
	@GetMapping("testInvokeInController")
	public String testAuditBill(@RequestParam String billId,
			@RequestParam(required=false,defaultValue="false") boolean isException,
			@RequestParam(required=false,defaultValue="false") boolean isExceptionInConfirm,
			@RequestParam(required=false,defaultValue="false") boolean isExceptionInCancel,
			@RequestParam(required=false,defaultValue="false") boolean isException_service2,
			@RequestParam(required=false,defaultValue="false") boolean isExceptionInConfirm_service2,
			@RequestParam(required=false,defaultValue="false") boolean isExceptionInCancel_service2
			) {
		servcie.auditBillForTcc(billId,isException,isExceptionInConfirm,isExceptionInCancel);
		Map<String,Object> queryMap = new HashMap<>();
		queryMap.put("billId", urlEncode(billId));
		queryMap.put("isException", isException_service2);
		queryMap.put("isExceptionInConfirm", isExceptionInConfirm_service2);
		queryMap.put("isExceptionInCancel", isExceptionInCancel_service2);
		String msg = restTemplate.getForObject(cseService2, String.class,queryMap);
		//if (true) throw PKDevException.throwException("审核主表在controller中，调用micservice2后发生异常.");
		return "审核成功-" + msg + "-end";
	}
	
}
